home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Telnet 2.6.1d1 4⁄26⁄94 Folder / source / main / event.c < prev    next >
Text File  |  1994-03-25  |  31KB  |  1,038 lines

  1. /*
  2. *    event.c
  3. *****************************************************************
  4. *    NCSA Telnet for the Macintosh                                *
  5. *                                                                *
  6. *    National Center for Supercomputing Applications                *
  7. *    Software Development Group                                    *
  8. *    152 Computing Applications Building                            *
  9. *    605 E. Springfield Ave.                                        *
  10. *    Champaign, IL  61820                                        *
  11. *                                                                *
  12. *    Copyright (c) 1986-1993,                                    *
  13. *    Board of Trustees of the University of Illinois                *
  14. *****************************************************************
  15. *
  16. *    Main Event loop code for NCSA Telnet for the Macintosh
  17. *
  18. *    Called by:
  19. *        maclook.c
  20. *
  21. *    Revisions:
  22. *    7/92    Telnet2.6:    added 2 support for 2 global structs, put cursors into
  23. *                        an array, cleaned up defines            Scott Bulmahn                        
  24. *
  25. */
  26.  
  27. #ifdef MPW
  28. #pragma segment 4
  29. #endif
  30.  
  31. /*
  32.  *    Files for inclusion.
  33.  */
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <string.h>
  37. #include <EPPC.h>
  38. #include <AppleEvents.h>
  39.  
  40. #include "TelnetHeader.h"
  41. #include "VSkeys.h"
  42. #include "wind.h"
  43.  
  44. #include "network.proto.h"
  45. #include "mydnr.proto.h"
  46. #include "bkgr.proto.h"
  47. #include "maclook.proto.h"
  48. #include "InternalEvents.h"
  49. #include "vsdata.h"
  50. #include "vsinterf.proto.h"
  51. #include "menuseg.proto.h"
  52. #include "vrrgmac.proto.h"
  53. #include "tekrgmac.proto.h"
  54. #include "rsmac.proto.h"
  55. #include "event.proto.h"
  56. #include "macros.proto.h"                /* For setmacro proto */
  57. #include "netevent.proto.h"
  58. #include "translate.proto.h"
  59. #include "parse.proto.h"
  60. #include "ftpbin.proto.h"
  61. #include "debug.h"
  62. #include "Connections.proto.h"
  63.  
  64. extern short        scrn;
  65. extern MenuHandle    myMenus[NMENUS];
  66. extern Boolean        gKeyboardHasControlKey;
  67. extern SysEnvRec    theWorld;        /* BYU 2.4.12 - System Environment record */
  68. extern WindRec        *screens,
  69.                     *ftplog;
  70. extern Cursor        *theCursors[];
  71.  
  72. /*
  73.  *    Declarations for constant variables
  74.  */
  75.  
  76. unsigned char kpxlate[2][62] =
  77.   /* table for translating virtual scan codes to internal codes for
  78.     special keys. */
  79.   {
  80.       {        /* virtual key code */
  81.         VSKP,    /* $41 */
  82.         VSRT,    /* $42 (Mac+) */
  83.         VSF4,    /* $43 (ADB) */
  84.         0,        /* $44 */
  85.         VSKC,    /* $45 (ADB std) */
  86.         VSLT,    /* $46 (Mac+) */
  87.         VSF1,    /* $47 */
  88.         VSDN,    /* $48 (Mac+) */
  89.         0,        /* $49 */
  90.         0,        /* $4A */
  91.         VSF3,    /* $4B (ADB) */
  92.         VSKE,    /* $4C */
  93.         VSUP,    /* $4D (Mac+) */
  94.         VSKM,    /* $4E */
  95.         0,        /* $4F */
  96.         0,        /* $50 */
  97.         VSF2,    /* $51 (ADB) */
  98.         VSK0,    /* $52 */
  99.         VSK1,    /* $53 */
  100.         VSK2,    /* $54 */
  101.         VSK3,    /* $55 */
  102.         VSK4,    /* $56 */
  103.         VSK5,    /* $57 */
  104.         VSK6,    /* $58 */
  105.         VSK7,    /* $59 */
  106.         0,        /* $5A */
  107.         VSK8,    /* $5B */
  108.         VSK9,    /* $5C */
  109.         0,        /* $5D */
  110.         0,        /* $5E */
  111.         0,        /* $5F */
  112.         VSF10,    /* $60 */    /* BYU 2.4.12 */
  113.         VSF11,    /* $61 */    /* BYU 2.4.12 */
  114.         VSF12,    /* $62 */    /* BYU 2.4.12 */
  115.         VSF8,    /* $63 */    /* BYU 2.4.12 - was VSF3 */
  116.         VSF13,    /* $64 */    /* BYU 2.4.12 */
  117.         VSF14,    /* $65 */    /* BYU 2.4.12 */
  118.         0,        /* $66 */
  119.         VSF16,    /* $67 */    /* BYU 2.4.12 */
  120.         0,        /* $68 */
  121.         VSF18,    /* $69 */    /* BYU 2.4.12 */
  122.         0,        /* $6A */
  123.         VSF19,    /* $6B */    /* BYU 2.4.12 */
  124.         0,        /* $6C */
  125.         VSF15,    /* $6D */    /* BYU 2.4.12 */
  126.         0,        /* $6E */
  127.         VSF17,    /* $6F */    /* BYU 2.4.12 */
  128.         0,        /* $70 */
  129.         VSF20,    /* $71 */    /* BYU 2.4.12 */
  130.         VSHELP,    /* $72 */    /* BYU 2.4.12 */
  131.         VSHOME,    /* $73 */    /* BYU 2.4.12 */
  132.         VSPGUP,    /* $74 */    /* BYU 2.4.12 */
  133.         VSDEL,    /* $75 (ADB ext) */        /* BYU 2.4.12 - was 0x7f */
  134.         VSF9,    /* $76 */    /* BYU 2.4.12 - was VSF4 */
  135.         VSEND,    /* $77 */    /* BYU 2.4.12 */
  136.         VSF7,    /* $78 */    /* BYU 2.4.12 - was VSF2 */
  137.         VSPGDN,    /* $79 */    /* BYU 2.4.12 */
  138.         VSF6,    /* $7A */    /* BYU 2.4.12 - was VSF1 */
  139.         VSLT,    /* $7B */
  140.         VSRT,    /* $7C */
  141.         VSDN,    /* $7D */
  142.         VSUP    /* $7E */
  143.       },
  144.       {
  145.         VSKP,    /* $41 */
  146.         VSF4,    /* $42 (Mac+) */
  147.         VSF4,        /* $43 (ADB) */
  148.         0,        /* $44 */
  149.         VSKC,        /* $45 (ADB) */
  150.         VSKC,    /* $46 (Mac+) */
  151.         VSF1,    /* $47 */
  152.         VSF2,    /* $48 */
  153.         0,        /* $49 */
  154.         0,        /* $4A */
  155.         VSF3,        /* $4B */
  156.         VSKE,    /* $4C */
  157.         VSF3,    /* $4D */
  158.         VSKM,        /* $4E */
  159.         0,        /* $4F */
  160.         0,        /* $50 */
  161.         VSF2,        /* $51 */
  162.         VSK0,    /* $52 */
  163.         VSK1,    /* $53 */
  164.         VSK2,    /* $54 */
  165.         VSK3,    /* $55 */
  166.         VSK4,    /* $56 */
  167.         VSK5,    /* $57 */
  168.         VSK6,    /* $58 */
  169.         VSK7,    /* $59 */
  170.         0,        /* $5A */
  171.         VSK8,    /* $5B */
  172.         VSK9,    /* $5C */
  173.         0,        /* $5D */
  174.         0,        /* $5E */
  175.         0,        /* $5F */
  176.         VSF10,    /* $60 */    /* BYU 2.4.12 */
  177.         VSF11,    /* $61 */    /* BYU 2.4.12 */
  178.         VSF12,    /* $62 */    /* BYU 2.4.12 */
  179.         VSF8,    /* $63 */    /* BYU 2.4.12 - was VSF3 */
  180.         VSF13,    /* $64 */    /* BYU 2.4.12 */
  181.         VSF14,    /* $65 */    /* BYU 2.4.12 */
  182.         0,        /* $66 */
  183.         VSF16,    /* $67 */    /* BYU 2.4.12 */
  184.         0,        /* $68 */
  185.         VSF18,    /* $69 */    /* BYU 2.4.12 */
  186.         0,        /* $6A */
  187.         VSF19,    /* $6B */    /* BYU 2.4.12 */
  188.         0,        /* $6C */
  189.         VSF15,    /* $6D */    /* BYU 2.4.12 */
  190.         0,        /* $6E */
  191.         VSF17,    /* $6F */    /* BYU 2.4.12 */
  192.         0,        /* $70 */
  193.         VSF20,    /* $71 */    /* BYU 2.4.12 */
  194.         VSHELP,    /* $72 */    /* BYU 2.4.12 */
  195.         VSHOME,    /* $73 */    /* BYU 2.4.12 */
  196.         VSPGUP,    /* $74 */    /* BYU 2.4.12 */
  197.         VSDEL,    /* $75 (ADB ext) */        /* BYU 2.4.12 - was 0x7f */
  198.         VSF9,    /* $76 */    /* BYU 2.4.12 - was VSF4 */
  199.         VSEND,    /* $77 */    /* BYU 2.4.12 */
  200.         VSF7,    /* $78 */    /* BYU 2.4.12 - was VSF2 */
  201.         VSPGDN,    /* $79 */    /* BYU 2.4.12 */
  202.         VSF6,    /* $7A */    /* BYU 2.4.12 - was VSF1 */
  203.         VSLT,    /* $7B */
  204.         VSRT,    /* $7C */
  205.         VSDN,    /* $7D */
  206.         VSUP    /* $7E */
  207.       }
  208.   };
  209.  
  210. /* ASCII character set defines */
  211.  
  212. #define DELchar        0x7f    /* BYU LSC - (DEL is defined in MacLook.h) the delete character */
  213. #define    KILLCHAR    0x15    /* the character to kill the local line with */
  214.  
  215. #include "event.proto.h"
  216.  
  217. short updateCursor(short force)
  218. {
  219.     static Point    lastPoint;
  220.     static short    optwasdown;
  221.     short            optDown;
  222.     Point            myPoint;
  223.     unsigned char    allthekeys[16];            /* Someplace to put the keymap */
  224.  
  225.     if (TelInfo->myfrontwindow) {                    /* BYU 2.4.11 */
  226.         SetPort((GrafPtr) TelInfo->myfrontwindow);    /* BYU 2.4.11 */
  227.     } else {                                /* BYU 2.4.11 */
  228.         SetCursor(theCursors[normcurs]);                /* BYU 2.4.11 */
  229.         return(0);                            /* BYU 2.4.11 */
  230.     }
  231.  
  232.     GetMouse(&myPoint);
  233.  
  234.     GetKeys((long *) allthekeys);
  235.     optDown = allthekeys[7] &4;
  236.  
  237.     if ( (!force) && EqualPt(myPoint,lastPoint) && (optDown ==optwasdown))
  238.         return(0);
  239.  
  240.     if (force)
  241.         TelInfo->lastCursor=0L;
  242.     if (TelInfo->ginon) {
  243.         if (TelInfo->lastCursor!= theCursors[gincurs]) {
  244.             SetCursor(theCursors[gincurs]);
  245.             TelInfo->lastCursor = theCursors[gincurs];
  246.             }
  247.         return(1);
  248.         }
  249.  
  250.     if (TelInfo->xferon && !optDown) {
  251.         if  (TelInfo->lastCursor!= theCursors[xfercurs]) {
  252.             SetCursor( theCursors[xfercurs]);
  253.             TelInfo->lastCursor = theCursors[xfercurs];
  254.             }
  255.         return(1);
  256.         }
  257.  
  258.     switch (TelInfo->myfronttype) {
  259.         case DEC_WINDOW:
  260.             if (RSmouseintext( TelInfo->myfrontvs, myPoint)) {
  261.                 if (optDown) {                /* Option key is down */
  262.                     if (TelInfo->lastCursor != theCursors[poscurs]) {
  263.                         TelInfo->lastCursor  = theCursors[poscurs];
  264.                         SetCursor(theCursors[poscurs]);
  265.                         }
  266.                 } else {
  267.                     if (TelInfo->lastCursor != theCursors[textcurs]) {
  268.                         TelInfo->lastCursor  = theCursors[textcurs];
  269.                         SetCursor(theCursors[textcurs]);
  270.                         }
  271.                     }
  272.             } else {
  273.                 if (TelInfo->lastCursor != theCursors[normcurs]) {
  274.                     TelInfo->lastCursor  = theCursors[normcurs];
  275.                     SetCursor(theCursors[normcurs]);
  276.                     }
  277.             }
  278.             break;
  279.         case TEK_WINDOW:
  280.             LocalToGlobal(&myPoint);
  281.             if (PtInRgn(myPoint, TelInfo->myfrontwindow->contRgn)) {        /* BYU LSC */
  282.                 if (TelInfo->lastCursor != theCursors[graphcurs]) {
  283.                     TelInfo->lastCursor  = theCursors[graphcurs];
  284.                     SetCursor(theCursors[graphcurs]);
  285.                     }
  286.             } else {
  287.                 if (TelInfo->lastCursor != theCursors[normcurs]) {
  288.                     TelInfo->lastCursor  = theCursors[normcurs];
  289.                     SetCursor(theCursors[normcurs]);
  290.                     }
  291.             }
  292.             break;
  293.         case NO_WINDOW:
  294.         default:
  295.             if (force) {
  296.                 SetCursor( theCursors[normcurs]);
  297.                 TelInfo->lastCursor= theCursors[normcurs];
  298.                 }
  299.         }
  300.     lastPoint=myPoint;
  301.     optwasdown=optDown;
  302.     return(0);
  303. }
  304.  
  305. void NoWindow( void)
  306. {
  307.         TelInfo->myfrontwindow=0L;
  308.         TelInfo->myfronttype=NO_WINDOW;
  309.         TelInfo->myfrontRgn=0L;
  310.         updateCursor(1);
  311. }
  312.  
  313. /*     The following code was graciously donated by Marc Tamsky.  When are YOU going to donate
  314.     YOUR code, eh?  We know you're reading this.  -- JMB */
  315.  
  316. Boolean CheckPageKeys(short code)                                            /* NCSA: SB */
  317. {                                                                            /* NCSA: SB */
  318.     GrafPtr currFW;     // current front window holder                      // MAT--
  319.     short     ourW;       // virtual screen number holder                     // MAT--kinda
  320.     short     x1, y2, x2, y1; // coordinates from window                      // MAT--pulled from scrollproc
  321.                                                                             /* NCSA: SB */
  322.     currFW = (GrafPtr)FrontWindow();                                        // MAT--
  323.     ourW = RSfindvwind(currFW);                                             // MAT--
  324.                                                                             /* NCSA: SB */    
  325.     switch (code)                                                            /* NCSA: SB */
  326.         {                                                                    /* NCSA: SB */
  327.         case VSPGUP:                                                        /* NCSA: SB */
  328.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                               // MAT--
  329.             VSscrolback(ourW, y2 - y1); /* scroll a whole windowful */      // MAT--
  330.             return TRUE;                                                       // MAT--
  331.             break;                                                            /* NCSA: SB */                                                            
  332.                                                                             /* NCSA: SB */
  333.         case VSPGDN:                                                           // MAT--121 is a PAGE DOWN.                                                                          
  334.                                                                             // MAT--in rsmac.c
  335.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                             // MAT--
  336.             VSscrolforward(ourW, y2 - y1); /* scroll a whole windowful */   // MAT--
  337.             return TRUE;                                                    // MAT--
  338.             break;                                                             /* NCSA: SB */
  339.                                                                               // MAT--
  340.         case VSHOME:                                                        /* NCSA: SB */
  341.             VSscroltop(ourW);                                                /* JMB 2.6 -- Created VSscroltop just for this purpose */
  342.             return TRUE;                                                    /* NCSA: SB */
  343.             break;                                                             // MAT--
  344.                                                                                // MAT--
  345.         case VSEND:                                                            /* NCSA: SB */
  346.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                             // MAT--
  347.             VSscrolforward(ourW, 32765); /* scroll a whole BUNCH! */        // MAT-- kludge time again.  anyone suggest
  348.             return TRUE;                                                    /* NCSA: SB */
  349.             break;                                                             // MAT--  a better way to hack this part?
  350.         }                                                                   // MAT--
  351.                                                                             /* NCSA: SB */
  352.     return FALSE;            /* NCSA: SB - we didnt handle event, let us know about it */
  353. }                                                                            /* NCSA: SB */
  354.  
  355. /*----------------------------------------------------------------------------------*/
  356. /*  SendOneChar --                                                                    */
  357. /*    This code was moved out of HandleKeyDown also, and made into one chunk of code.        */
  358. /*    Basically I got tired of looking at this code all over HandleKeyDown,                     */
  359. /*    so I put it here -- SMB.  Take one char, and write it to the network.  If it    */
  360. /*    needs to be echoed, then send it off to parse...         -SMB                    */    
  361.     
  362. void SendOneChar(unsigned char sendch)                        /* NCSA: SB */
  363. {                                                            /* NCSA: SB */
  364.     if (screens[scrn].echo && screens[scrn].halfdup)         /* NCSA: SB - support local echo */
  365.         parse( &screens[scrn], &sendch, 1);                    /* NCSA: SB */
  366.                                                             /* NCSA: SB */
  367.     netwrite(screens[scrn].port,&sendch,1);                    /* NCSA: SB */
  368.     netpush(screens[scrn].port);                            /* NCSA: SB */
  369. }                                                            /* NCSA: SB */
  370.  
  371. /*  HandleKeyDown --
  372.         By now, we have already gotten a keypress signal from the event handler, so we
  373.         just need to interpret it.  Get the    raw code and ascii value, and then decide
  374.         what to do with it.    */    
  375.  
  376. void HandleKeyDown(EventRecord theEvent)
  377. {
  378.     unsigned char ascii, code;
  379.     unsigned char sendch;
  380.     long    menuEquiv;
  381.     short    enterkey = 0;
  382.     Boolean    commanddown, optiondown, controldown;
  383.         
  384.     ObscureCursor();
  385.  
  386.     // We don't muck with the KCHR anymore, let the system do that!
  387.     
  388.     ascii = theEvent.message & charCodeMask;
  389.     code = ((theEvent.message & keyCodeMask) >> 8);
  390.     commanddown = ((theEvent.modifiers & cmdKey) != 0);
  391.     optiondown = ((theEvent.modifiers & optionKey) != 0);
  392.     controldown = ((theEvent.modifiers & controlKey) != 0);
  393.  
  394.     if (DebugKeys(commanddown, ascii, scrn))    // Handle debug info keys
  395.             return;
  396.             
  397.     //    Check for EMACS meta key hack first.
  398.     /* NCSA: SB - here is where we are going to check if it is an option-escape mapping */
  399.     /* NCSA: SB - If so, handle the keypress and return                                    */
  400.     if (screens[scrn].emacsmeta && !screens[scrn].ftpstate &&
  401.         commanddown && controldown && (ascii >= 1 && ascii < ESC))    /* NCSA: SB */
  402.         {                                                                        /* NCSA: SB */                
  403.         if (screens[scrn].lmode)                                                /* NCSA: SB */
  404.             {                                                                    /* NCSA: SB */
  405.             netwrite( screens[scrn].port, screens[scrn].kbbuf                    /* NCSA: SB */
  406.                     , screens[scrn].kblen);                                        /* NCSA: SN - flush buffer */
  407.             screens[scrn].kblen=0;                                                /* NCSA: SB */
  408.             }                                                                    /* NCSA: SB */
  409.         ascii |= 0x60;                                                            /* NCSA: SB */
  410.         SendOneChar(ESC);                                /* NCSA: SB - send the ESC char first */
  411.         SendOneChar(ascii);                                /* NCSA: SB - now send the char */
  412.         return;                                            /* NCSA: SB - we handled the char, so return */
  413.         }
  414.     
  415.     //    Handle command keys first (if CommandKeys preference is set to TRUE)
  416.     if (commanddown && gApplicationPrefs->CommandKeys) {
  417.         menuEquiv = MenuKey(ascii);
  418.         if ((menuEquiv & 0xFFFF0000) != 0) {
  419.             HandleMenuCommand(menuEquiv,theEvent.modifiers);
  420.             return;
  421.             }
  422.         }
  423.  
  424.     //    If the keyboard has no control key and command keys are off, remap the command
  425.     //    key to control
  426.     if (commanddown && !gApplicationPrefs->CommandKeys && !gKeyboardHasControlKey) {
  427.         commanddown = 0;    
  428.         controldown = 1;
  429.         }
  430.     
  431.     //    Control-Space results in 0 ASCII    
  432.     if (controldown && (ascii == 32))
  433.                 ascii=0;            /* ASCII nul value for command-spacebar */
  434.  
  435.     /* Remap PgUp,PgDown,Home,End if the user wants it that way */
  436.     if (screens[scrn].pgupdwn && !screens[scrn].ftpstate && (code >= KPlowest)) 
  437.         if (CheckPageKeys(code)) return;        
  438.  
  439.     /* The rest of HandleKeyDown doesn't make any sense if the window is a corpse.
  440.         So we can just return out in that case */
  441.     if (screens[scrn].active == CNXN_ISCORPSE) return;
  442.  
  443.     if (commanddown)  {        /* handle key macros */
  444.         if (ascii >='0' && ascii <='9' )  {
  445.             sendmacro( ascii-'0');
  446.             return;
  447.             }
  448.         }
  449.  
  450.     //    If we are mapping "`" to ESC, do it unless the command key is down.
  451.     if (ascii == '`' && gApplicationPrefs->RemapTilde && (!commanddown))
  452.         ascii = ESC;
  453.  
  454.     /*    If there are no active windows, or if user has hit a command key that doesn't
  455.         correspond to a menu or a tilde remap override, ignore the key event */
  456.     if (TelInfo->numwindows<1 || (    (commanddown) && 
  457.                                     gApplicationPrefs->CommandKeys &&
  458.                                     ascii != '`' ))
  459.         return;
  460.  
  461.     if (!screens[scrn].ftpstate && (code >= KPlowest)) {        /* BYU - Handle Keypad */
  462.         short shifted;
  463.         shifted = ((theEvent.modifiers & shiftKey) != 0);
  464.         if (theWorld.keyBoardType == envStandADBKbd)            /* BYU 2.4.12 */
  465.             if (code == 0x45)    code = 0x4e;
  466.             else if (code == 0x4e)    code = 0x45;
  467.             
  468.         ascii = kpxlate[shifted][code - KPlowest];
  469.         // Should we check here for ascii being zero?
  470.         VSkbsend(screens[scrn].vs, (unsigned char) ascii, screens[scrn].echo);
  471.         return;
  472.       }
  473.  
  474.  
  475.     /* BSD-like mapping.... if we don't want this, set chars to zero and it wont work */
  476.     if (ascii == screens[scrn].TELstop)  {
  477.         screens[scrn].enabled = 0;
  478.         return;
  479.         }
  480.  
  481.     if (ascii == screens[scrn].TELgo) {
  482.         screens[scrn].enabled = 1;
  483.         return;
  484.         }
  485.         
  486.     if (ascii == screens[scrn].TELip)  {
  487.         netpush(screens[scrn].port);
  488.         netwrite(screens[scrn].port, "\377\364",2);
  489.         screens[ scrn].timing = 1;                            /* set emulate to TMwait */
  490.         netwrite(screens[scrn].port, "\377\375\006",3);        /* send TM */
  491.         if (screens[scrn].lmode) 
  492.             screens[scrn].kblen=0;
  493.         return;
  494.         }
  495.  
  496.     //    Handle whatever mapping is needed.
  497.     mac_nat(&ascii, screens[scrn].national); /* LU/PM: Convert char to US */
  498.     
  499.     //    If bsdel is set and the "delete" key was hit, make the ascii a Delete character
  500.     if ((screens[scrn].bsdel) && (code == BScode)) ascii = DELchar;
  501.  
  502.     //    If the option key or command key is down, flip BS and DEL
  503.     if (theEvent.modifiers & (optionKey | cmdKey) && (code == BScode))
  504.             if (screens[scrn].bsdel) ascii = BS;
  505.                 else ascii = DEL;
  506.  
  507.     //    If we have a Mac Plus keyboard and not using command keys, command = control key
  508.     if (commanddown && !gApplicationPrefs->CommandKeys && !gKeyboardHasControlKey)
  509.         ascii &= 0x1f;
  510.                 
  511.     if (screens[scrn].ftpstate)                            /* BYU - ftpclient */
  512.         {                                                /* BYU */
  513.         if (ascii>31 && ascii != 127 && ascii < 255 && code<KPlowest)    /* BYU - add these chars to buffer */
  514.             {                                            /* BYU */
  515.             if (screens[scrn].kblen < (MAXKB -1))         /* BYU - Add to buffer if not full */
  516.                 {                                        /* BYU */
  517.                 screens[scrn].kbbuf[ screens[scrn].kblen++ ] = ascii;    /* BYU */
  518.                 sendch=ascii;                            /* BYU */
  519.                 parse( &screens[ scrn], &sendch, 1);    /* BYU */
  520.                 }                                        /* BYU */
  521.             else                                         /* BYU */
  522.                 SysBeep(4);                                /* BYU - buffer full */
  523.             }                                            /* BYU */
  524.         else                                            /* BYU - not printable char */
  525.             {                                            /* BYU */
  526.             if ( code == BScode )                         /* BYU */
  527.                 {                                        /* BYU */
  528.                 if (screens[scrn].kblen>0)                 /* BYU */
  529.                     {                                    /* BYU */
  530.                     screens[scrn].kblen--;                    /* BYU */
  531.                     parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU */
  532.                     }                                        /* BYU */
  533.                 }                                        /* BYU */
  534.             else if (ascii == CR)                        /* BYU */
  535.                 {                                        /* BYU */
  536.                 parse( &screens[scrn],(unsigned char *) "\015\012",2);        /* BYU */
  537.                 screens[scrn].kbbuf[ screens[scrn].kblen++ ] = 0;    /* BYU */
  538.                 ftppi(screens[scrn].kbbuf);                            /* BYU - ftp client */
  539.                 screens[scrn].kblen=0;                    /* BYU */
  540.                 }                                        /* BYU */
  541.             else if (ascii == KILLCHAR)                 /* BYU */
  542.                 {                                        /* BYU */
  543.                 while (screens[scrn].kblen >0)             /* BYU */
  544.                     {                                        /* BYU */
  545.                     parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU */
  546.                     screens[scrn].kblen--;                    /* BYU */
  547.                     }                                    /* BYU */
  548.                 }
  549.             }
  550.         return;                                            /* BYU */
  551.         }
  552.  
  553.     else if (screens[scrn].lmode)    /* Some form of linemode is active */
  554.         {
  555.         if (screens[scrn].lmode & 2) {        // TRAPSIG mode active
  556.             char vtemp[5];
  557.     
  558.             
  559.             switch (ascii) {
  560.                 case 26:
  561.                         netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);    /* if full send buffer */
  562.                         screens[scrn].kblen=0;
  563.                         sprintf(vtemp,"%c%c",255,237);    // IAC SUSP
  564.                         netwrite(screens[scrn].port,vtemp,2);
  565.                     break;
  566.                 case 3: 
  567.                         netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);    /* if full send buffer */
  568.                         screens[scrn].kblen=0;
  569.                         sprintf(vtemp,"%c%c",255,244);    // IAC ABORT
  570.                         netwrite(screens[scrn].port,vtemp,2);
  571.                     break;
  572.                 }
  573.             }
  574.                     
  575.         if (screens[scrn].echo && ! screens[scrn].halfdup)    /* Handle local ECHOs */
  576.  
  577.             if (ascii>31 && ascii <127 && code<KPlowest)    /* add these chars to buffer */
  578.                 {
  579.                 if (screens[scrn].kblen < (MAXKB -1))     /* Add to buffer if not full */
  580.                     screens[scrn].kbbuf[ screens[scrn].kblen++ ] = ascii;
  581.                 else 
  582.                     {                
  583.                     netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);    /* if full send buffer */
  584.                     screens[scrn].kbbuf[0]=ascii;
  585.                     screens[scrn].kblen=1;
  586.                     }
  587.  
  588.                 sendch=ascii;
  589.                 parse( &screens[ scrn], &sendch, 1);
  590.                 if (!screens[scrn].halfdup)    
  591.                     return;                                /* OK, were set...*/
  592.     
  593.                 }
  594.              else                    /* not printable char */
  595.                 {
  596.                 if ( code == BScode ) 
  597.                     {
  598.                     if (screens[scrn].kblen>0) 
  599.                         {
  600.                         screens[scrn].kblen--;
  601.                         parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU LSC */
  602.                         }
  603.                     return;
  604.                     }
  605.                 else if (ascii == CR) 
  606.                     {
  607.                     char tt[50];
  608.                     
  609.                     netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);
  610.                     sprintf(tt,"LINEMODE: length %i ",(int)screens[scrn].kblen);
  611.                     putln(tt);
  612.                     screens[scrn].kblen=0;
  613.                     }
  614.     
  615.                 else if (ascii == KILLCHAR) 
  616.                     {
  617.                     while (screens[scrn].kblen >0) 
  618.                         {
  619.                         parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU LSC */
  620.                         screens[scrn].kblen--;
  621.                         }
  622.                     return;
  623.                     }
  624.  
  625.                 else if (code <KPlowest) 
  626.                     {
  627.                     netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);    /* if full send buffer */
  628.                     screens[scrn].kblen=0;
  629.                     
  630.                     if (ascii != CR) {
  631.                         sendch='@'+ascii;
  632.                         parse( &screens[scrn],(unsigned char *) "^",1);
  633.                         parse( &screens[scrn], &sendch, 1);
  634.                         }
  635.                     }
  636.                 }
  637.             }
  638.             
  639.     else        /* BYU = was: if (!screens[scrn].lmflag ) */
  640.         {
  641.         if (screens[scrn].echo && ! screens[scrn].halfdup)        /* Handle local ECHOs */
  642.             if (ascii>31 && ascii <127 && code<KPlowest)    
  643.                 {
  644.                 if (screens[scrn].kblen < (MAXKB -1))     /* Add to buffer if not full */
  645.                     screens[scrn].kbbuf[ screens[scrn].kblen++ ] = ascii;
  646.                 else 
  647.                     {                    
  648.                     netwrite( screens[scrn].port, screens[scrn].kbbuf,
  649.                     screens[scrn].kblen);    /* if full send buffer */    
  650.                     screens[scrn].kbbuf[ 0 ]=ascii;
  651.                     screens[scrn].kblen=1;
  652.                     }
  653.  
  654.                 sendch=ascii;
  655.                 parse( &screens[ scrn], &sendch, 1);
  656.                 if (!screens[scrn].halfdup)    
  657.                     return;                                /* OK, were set...*/
  658.                 }
  659.             else 
  660.                 {
  661.                 if ( code == BScode ) 
  662.                     {
  663.                     if (screens[scrn].kblen>0) 
  664.                         {
  665.                         screens[scrn].kblen--;
  666.                         parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU LSC */
  667.                         }
  668.                     return;
  669.                     }
  670.                 else if (ascii == KILLCHAR) 
  671.                     {
  672.                     while (screens[scrn].kblen >0) 
  673.                         {
  674.                         parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU LSC */
  675.                         screens[scrn].kblen--;
  676.                         }
  677.                     return;
  678.                     }
  679.         
  680.                 else if (code <KPlowest) 
  681.                     {
  682.                     netwrite( screens[scrn].port, screens[scrn].kbbuf,
  683.                     screens[scrn].kblen);    /* if full send buffer */
  684.                     screens[scrn].kblen=0;
  685.                     if (ascii !=CR) 
  686.                         {
  687.                         sendch='@'+ascii;
  688.                         parse( &screens[scrn],(unsigned char *) "^",1);    /* BYU LSC */
  689.                         parse( &screens[scrn], &sendch, 1);
  690.                         }
  691.                     }
  692.                 }
  693.             }
  694.             
  695.  
  696.     if (ascii == '\015')                         /* BYU 2.4.18 - changed \n to \015 */
  697.         {        /* Map CR->CRLF */
  698.         netpush( screens[scrn].port);
  699.         
  700.         //    If crmap is on, send CR-NULL instead of CR-LF.  If linemode is on, ignore crmap option.
  701.         if (!screens[scrn].lmode && screens[scrn].crmap) { 
  702.             netwrite(screens[scrn].port,"\015",1);
  703.             ascii = 0;
  704.             }
  705.         else if (screens[scrn].lmode)
  706.             {
  707.             ascii = '\012';
  708.             }
  709.         else
  710.             {
  711.             netwrite(screens[scrn].port,"\015",1);
  712.             ascii = '\012';
  713.             }
  714.             
  715.         if (screens[scrn].echo) parse( &screens[scrn],(unsigned char *) "\012\015",2);    /* BYU LSC */
  716.         }
  717.  
  718.  
  719.     // Don't use SendOneChar here because we have to double ASCII 255 to escape its effect
  720.     // as the IAC character.
  721.     if (screens[scrn].echo && screens[scrn].halfdup) 
  722.         {
  723.         sendch=ascii;
  724.         parse( &screens[scrn], &sendch, 1);
  725.         }
  726.  
  727.     if (ascii != 255) {
  728.         sendch= ascii;
  729.         netwrite(screens[scrn].port,&sendch,1);
  730.         }
  731.     else
  732.         netwrite(screens[scrn].port, "\377\377", 2);
  733.         
  734.     netpush(screens[scrn].port);                    
  735. }
  736.  
  737. void    HandleMouseDown(EventRecord myEvent)
  738. {
  739.     GrafPtr    whichWindow;
  740.     short    code, myRGMnum;
  741.     
  742.     code = FindWindow(myEvent.where, &whichWindow);
  743.     
  744.     switch (code) {
  745.         case inMenuBar:
  746.             HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers);    /* BYU LSC */
  747.             break;
  748.         case inSysWindow:
  749.             SystemClick(&myEvent, whichWindow);
  750.             break;
  751.         case inGoAway:
  752.             if (TrackGoAway( whichWindow, myEvent.where))
  753.                 CloseAWindow((WindowPtr)whichWindow);
  754.             break;
  755.  
  756.         case inDrag:
  757.             if ((whichWindow != FrontWindow()) &&
  758.                     (!(myEvent.modifiers & cmdKey)) &&
  759.                     (!(myEvent.modifiers & optionKey))) {
  760.                 SelectWindow(whichWindow);
  761.                 }
  762.             DragWindow(whichWindow, myEvent.where, &TelInfo->dragRect);
  763.             break;
  764.  
  765.         case inZoomIn:
  766.         case inZoomOut:
  767.             if (TrackBox( whichWindow, myEvent.where, code))
  768.                 RSzoom( whichWindow, code, myEvent.modifiers & shiftKey);
  769.             break;
  770.     
  771.     /* NCSA: SB - Telnet now allows you to grow the TEK window, finally.        */
  772.     /* NCSA: SB - So check to see if the click was in a TEK window                */
  773.     
  774.         case inGrow:
  775.             RSsize( whichWindow, (long *) &myEvent.where, myEvent.modifiers);
  776.             myRGMnum = RGfindbywind(whichWindow);            /* NCSA: SB - is it a TEK window click? */
  777.             if (myRGMnum  != -1)            /* NCSA: SB - Anyone want to play some BOLO? */
  778.                 {                                            /* NCSA: SB */
  779.                 RGMgrowme((short)myRGMnum, whichWindow,(long *) &myEvent.where,myEvent.modifiers);    /* NCSA: TG */
  780.                 }                                            /* NCSA: SB */
  781.         break;
  782.         
  783.         case inContent:
  784.             if (whichWindow != FrontWindow()) {
  785.                 SelectWindow(whichWindow);
  786.                 }
  787.             else
  788.                 if (RSclick(whichWindow, myEvent) <0) {
  789.                     SetPort(whichWindow);
  790.                     GlobalToLocal(&myEvent.where);
  791.                     RGmousedown(whichWindow, &myEvent.where );
  792.                     }
  793.             break;
  794.         
  795.         default:
  796.             break;
  797.     }
  798. }
  799.  
  800. void    DoEvents( void)
  801. {
  802.     Boolean        gotOne;            /* Did we get an event */
  803.     short        vs, i;
  804.     EventRecord    myEvent;
  805.     
  806.     gotOne = WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L);
  807.  
  808.     if (gotOne) {
  809.  
  810. /* BYU 2.4.11 - Turn the cursor off when the human makes the slightest move. */
  811.         if (gApplicationPrefs->BlinkCursor) {                                /* BYU 2.4.11 */
  812.             if ( (vs=RSfindvwind(FrontWindow())) >= 0)    /* BYU 2.4.11 */
  813.                 if (vs == screens[scrn].vs)                /* BYU 2.4.11 */
  814.                     if (!(myEvent.modifiers & cmdKey) &&    /* BYU 2.4.18 */
  815.                         ((myEvent.what == keyDown) || (myEvent.what == autoKey))
  816.                         )
  817.                         RScursblinkon(vs);                /* BYU 2.4.18 */
  818.                     else                                /* BYU 2.4.18 */
  819.                         RScursblinkoff(vs);                /* BYU 2.4.18 */
  820.         }                                                /* BYU 2.4.11 */
  821.  
  822.         switch(myEvent.what) {
  823.         case mouseDown:
  824.             HandleMouseDown(myEvent);
  825.             break;
  826.  
  827.         case updateEvt:
  828.             switch(((WindowPeek)myEvent.message)->windowKind) {
  829.                 case WIN_CONSOLE:
  830.                 case WIN_LOG:
  831.                 case WIN_CNXN:
  832.                     if (RSupdate((GrafPtr) myEvent.message))
  833.                         putln("Ack, problem in update!");
  834.                     break;
  835.                 
  836.                 case WIN_ICRG:
  837.                     if (MacRGupdate((WindowPtr) myEvent.message))
  838.                         putln("Ack, problem in update!");
  839.                     break;
  840.                     
  841.                 case WIN_TEK:
  842.                     if (RGupdate((GrafPtr) myEvent.message) ==0) 
  843.                         TekDisable(RGgetVG((GrafPtr) myEvent.message));
  844.                     else
  845.                         putln("Ack, problem in update!");
  846.                     break;
  847.                 
  848.                 default:
  849.                     putln("Bad windowkind!");
  850.                     break;
  851.                 }            
  852.             break;
  853.  
  854.         case keyDown:
  855.         case autoKey:
  856.             HandleKeyDown(myEvent);        /* All key events are processed through here */
  857.             break;
  858.  
  859.         case diskEvt:            /* check to see if disk needs to be initialized */
  860.             myEvent.where.h = 100;
  861.             myEvent.where.v = 120;
  862.             if (noErr != (( myEvent.message >> 16 ) & 0xffff )) {    /* check hi word */
  863.                 DILoad();
  864.                 DIBadMount( myEvent.where, myEvent.message);    /* BYU LSC */
  865.                 DIUnload();
  866.             }
  867.             break;
  868.  
  869.         case activateEvt:
  870.             if ((myEvent.modifiers & activeFlag)==1) {
  871.                 AdjustMenus();
  872.                 DrawMenuBar();
  873.                 i=WindowPtr2ScreenIndex((GrafPtr) myEvent.message);    /* We need to know who */
  874.                 if (i>=0) {
  875.                     if ((screens[i].curgraph>-1) && (!(myEvent.modifiers & optionKey)))
  876.                         detachGraphics(screens[i].curgraph);
  877.                     changeport(scrn,i);
  878.                     scrn=i;
  879.                     }
  880.                 if ((i=RSfindvwind((GrafPtr) myEvent.message))>=0) {
  881.                     if (RSTextSelected(i)) {                    /* BYU 2.4.11 */
  882.                         EnableItem(myMenus[Fil],FLprint);        /* BYU 2.4.11 */
  883.                         EnableItem(myMenus[Edit],EDcopy);        /* BYU 2.4.11 */
  884.                         EnableItem(myMenus[Edit],EDcopyt);        /* BYU 2.4.11 */
  885.                     } else {                                    /* BYU 2.4.11 */
  886.                         DisableItem(myMenus[Fil],FLprint);        /* BYU 2.4.11 */
  887.                         DisableItem(myMenus[Edit],EDcopy);        /* BYU 2.4.11 */
  888.                         DisableItem(myMenus[Edit],EDcopyt);        /* BYU 2.4.11 */
  889.                     }                                            /* BYU 2.4.11 */
  890.                     RSactivate(i);
  891.                     TelInfo->myfrontwindow=(WindowPeek) myEvent.message;
  892.                     TelInfo->myfronttype=DEC_WINDOW;
  893.                     TelInfo->myfrontvs = i;
  894.                     TelInfo->myfrontRgn =0L;
  895.                     updateCursor(1);
  896.                 } else {                    
  897.                     TelInfo->myfrontwindow=(WindowPeek) myEvent.message;
  898.                     TelInfo->myfronttype=TEK_WINDOW;
  899.                     TelInfo->myfrontRgn =0L;
  900.                     updateCursor(1);
  901.                     if ( (i = RGgetdnum((GrafPtr) myEvent.message)) >-1) {
  902.                         if (( i = RGgetVS( i)) >-1) {
  903.                             EnableItem(myMenus[Fil],FLprint);    /* BYU 2.4.11 - enable printing */
  904.                             EnableItem(myMenus[Edit],EDcopy);    /* BYU 2.4.11 - enable copying */
  905.                             DisableItem(myMenus[Edit],EDcopyt);    /* BYU 2.4.11 */
  906.                             i = findbyVS( i);
  907.                             changeport(scrn,i);
  908.                             scrn=i;
  909.                             }
  910.                         }
  911.                 }
  912.             } else {
  913.                 short i;
  914.  
  915. //                putln("disable event");
  916.                 AdjustMenus();
  917.                 DrawMenuBar();
  918.                 if ((i=RSfindvwind((GrafPtr) myEvent.message))>=0)
  919.                     RSdeactivate(i);
  920.                 NoWindow();
  921.                 }
  922.             break;
  923.         case app4Evt:
  924.             switch(( myEvent.message >>24) &0xff) {        /* App4 is a multi-event event */
  925.                 case switchEvt:
  926.                     if (myEvent.message & 0x20)
  927.                         /*Convert clipboard here if necc. (it is not)*/;
  928.  
  929.                     if (myEvent.message & 0x1) {        /* Resume Event */
  930.                         GrafPtr window;
  931.  
  932.                         TelInfo->suspended = FALSE;                /* We are no longer in suspension */
  933.                         DisableItem( myMenus[Edit],EDcut);
  934.                         DisableItem( myMenus[Edit],EDundo);
  935.                         DisableItem( myMenus[Edit],EDclear);
  936.  
  937.                         window = FrontWindow();            /* Who's on first */
  938.                         if ( (vs=RSfindvwind(window)) >= 0) {
  939.                             RSactivate(vs);
  940.                             TelInfo->myfrontwindow = (WindowPeek) window;
  941.                             TelInfo->myfronttype=DEC_WINDOW;
  942.                             TelInfo->myfrontvs = vs;
  943.                             TelInfo->myfrontRgn =0L;
  944.                             updateCursor(1);
  945.                         } else if ( (long)window != 0L) {
  946.                             myEvent.message = (long) window;
  947.                             myEvent.modifiers |= activeFlag;
  948.                             myEvent.what = activateEvt;
  949.                             myEvent.when = TickCount();
  950.                             SystemEvent( &myEvent);
  951.                             }
  952.                         }
  953.                     else {                                /* Suspend Event */
  954.                         GrafPtr window;
  955.  
  956.                         TelInfo->suspended=TRUE;                    /* We be in waitin' */
  957.                         EnableItem( myMenus[Edit],EDcut);
  958.                         EnableItem( myMenus[Edit],EDundo);
  959.                         EnableItem( myMenus[Edit],EDclear);
  960.  
  961.                         window = FrontWindow();            /* Who's on first */
  962.                         if ((window = FrontWindow())) {
  963.                             if ( (vs=RSfindvwind(window)) >= 0)
  964.                                 RSdeactivate(vs);
  965.                             else if ( (long)window != 0L) {
  966.                                 myEvent.message = (long) window;
  967.                                 myEvent.modifiers &= (~activeFlag);
  968.                                 myEvent.what = activateEvt;
  969.                                 myEvent.when = TickCount();
  970.                                 SystemEvent( &myEvent);
  971.                                 }
  972.                             }
  973.                         NoWindow();
  974.                         }
  975.                     break;            /* switch of myEvent.message >>24 */
  976.                 }
  977.             break;
  978.         case kHighLevelEvent:
  979.             (void) AEProcessAppleEvent(&myEvent);
  980.             break;            
  981.         }
  982.  
  983.     } else if (gApplicationPrefs->BlinkCursor && !TelInfo->suspended) {    /* BYU 2.4.11 */
  984.         if ( (vs=RSfindvwind(FrontWindow())) >= 0)        /* BYU 2.4.11 */
  985.             if (vs == screens[scrn].vs)                    /* BYU 2.4.11 */
  986.                 RScursblink(vs);                        /* BYU 2.4.11 */
  987.     }                                                    /* BYU 2.4.11 */
  988.     updateCursor(0);
  989. }
  990.  
  991. void    CloseAWindow(WindowPtr    theWindow)
  992. {
  993.     short    i;
  994.     
  995.     switch(((WindowPeek)theWindow)->windowKind) {
  996.         case WIN_CONSOLE:
  997. //            Debugger();                // Can't close the console window
  998.             break;
  999.                     
  1000.         case WIN_LOG:
  1001.             if (theWindow == ftplog->wind) {
  1002.                 CheckItem(myMenus[Fil],FLlog,FALSE);
  1003.                 TelInfo->ftplogon = FALSE;
  1004.                 RShide(ftplog->vs);
  1005.             }
  1006.             break;
  1007.                     
  1008.         case WIN_CNXN:
  1009.             if ((i = WindowPtr2ScreenIndex(theWindow)) >= 0) {
  1010.                 if ( screens[i].active == CNXN_ISCORPSE)
  1011.                     destroyport(i);
  1012.                 else {
  1013.                     if ( !ReallyClose( i) ) break;
  1014.                     netclose(screens[i].port);
  1015.                     removeport(i);
  1016.                     }
  1017.                 }
  1018.             break;
  1019.         
  1020.         case WIN_ICRG:
  1021.             MacRGdestroy(MacRGfindwind(theWindow));
  1022.             break;
  1023.             
  1024.         case WIN_TEK:
  1025.             destroyGraphics(RGgetVG(theWindow));
  1026.             break;
  1027.         
  1028.         default:
  1029.             DebugStr("\pBad windowkind!");
  1030.             break;
  1031.         }            
  1032.  
  1033.         NoWindow();
  1034. }
  1035.  
  1036.  
  1037.  
  1038.